Skip to content

feat(sdk): enforce log record attribute count limit#3571

Open
Wassbdr wants to merge 1 commit into
open-telemetry:mainfrom
Wassbdr:feat/log-attribute-count-limit
Open

feat(sdk): enforce log record attribute count limit#3571
Wassbdr wants to merge 1 commit into
open-telemetry:mainfrom
Wassbdr:feat/log-attribute-count-limit

Conversation

@Wassbdr

@Wassbdr Wassbdr commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Part of #3374. Prerequisite for #3568.

Context

In #3568 I added OTEL_ATTRIBUTE_COUNT_LIMIT for spans. @cijothomas pointed out that the general variable is meant to apply to logs too, and that the logs SDK does not enforce any attribute limit today — so exposing the general variable before logs support exists would mislead users. This PR adds that missing logs support first.

Change

SdkLoggerProvider now enforces a maximum attribute count per log record (default 128), dropping attributes added beyond the limit when the record is emitted. Configurable, in precedence order, via:

  1. LoggerProviderBuilder::with_max_attributes_per_log (code-based)
  2. OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT
  3. OTEL_ATTRIBUTE_COUNT_LIMIT (general fallback)
  4. default 128

Enforcement is done once in SdkLogger::emit, before the record is handed to processors, using a new GrowableArray::truncate. The limit is resolved at provider build time and stored on LoggerProviderInner.

This mirrors the span behavior (max_attributes_per_span + OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT) and keeps the hot path cheap: a single truncate per emitted record, a no-op when within the limit.

Notes / scope

  • Truncation drops the last-added attributes (keeping the first), matching the span limit semantics.
  • This PR does not surface a dropped_attributes_count on SdkLogRecord or wire it through OTLP (the proto transform currently sends 0). That's a separate, larger change and can follow; happy to do it if preferred.

Tests

  • GrowableArray::truncate unit test (inline region, overflow region, boundary, no-op, zero).
  • Logger provider tests: default limit truncates; within-limit kept; builder value wins; OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT over OTEL_ATTRIBUTE_COUNT_LIMIT; general var as fallback.

cargo test -p opentelemetry_sdk --all-features --lib, cargo clippy --all-targets --all-features -- -Dwarnings, and cargo fmt --all -- --check all pass.

}
logger.emit(record);
provider.force_flush().unwrap();
count

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no need to return the count here.

Comment thread opentelemetry-sdk/src/logs/logger.rs Outdated

// Enforce the configured attribute count limit before handing the
// record to processors, dropping the attributes added last.
record.truncate_attributes(provider.max_attributes_per_log() as usize);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the original intend behind enforcing this limit is to protect the sdk from taking up too much memory when a mistaken code adds too much attributes, then we should prevent it from being added in the first place. Truncating afterwards won't help.
Could you try eagerly checking the limit in each add_attribute() call? That'd also make it relatively easy to track the dropped count.
Please do benchmark and see if we regress measurably.

/// Attributes added beyond this limit are dropped when the record is
/// emitted. When not set, this is read from the
/// `OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT` environment variable, which falls
/// back to `OTEL_ATTRIBUTE_COUNT_LIMIT`, and otherwise defaults to `128`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: after this is merged, we should follow up immediately with your other PR so this variable will be consistently applied in spans too.

@Wassbdr Wassbdr force-pushed the feat/log-attribute-count-limit branch from a041a17 to 9b5265c Compare July 3, 2026 00:46
@Wassbdr

Wassbdr commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review @cijothomas — addressed all three:

Enforce eagerly in add_attribute + track dropped count. Reworked: enforcement now happens in SdkLogRecord::add_attribute, which rejects attributes once the limit is reached (the storage never grows past the limit) and increments a dropped_attributes_count, exposed via SdkLogRecord::dropped_attributes_count(). The limit is stamped onto the record at create_log_record time. Removed the emit-time truncation (and the now-unused GrowableArray::truncate).

Benchmark. Ran cargo bench --bench log-attributes (appender-tracing, 0–12 attributes) as an A/B of this branch vs main on the same machine. No regression on any case — criterion reports either "No change" or "improved". Representative:

case change vs main (p)
otel_0_attributes No change (p=0.61)
otel_2_attributes No change (p=0.15)
otel_5_attributes improved (p=0.00)
otel_10_attributes improved (p=0.00)

(The machine is a noisy WSL2 box, so the "improved" deltas are noise; the point is nothing regressed. The added cost is a single len() < max comparison per attribute.)

nit: helper return value / follow-up PR. Removed the unused return from emit_record_with_attributes. And yes — once this lands I'll rebase #3568 so OTEL_ATTRIBUTE_COUNT_LIMIT is applied consistently to spans too.

One scope note: this tracks dropped_attributes_count on the record but does not yet wire it through the OTLP proto transform (still sends 0). Happy to do that here or as a fast follow — let me know your preference.

@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.2%. Comparing base (7b24be9) to head (e4ed69c).

Additional details and impacted files
@@           Coverage Diff           @@
##            main   #3571     +/-   ##
=======================================
+ Coverage   83.0%   83.2%   +0.1%     
=======================================
  Files        130     130             
  Lines      28064   28228    +164     
=======================================
+ Hits       23321   23496    +175     
+ Misses      4743    4732     -11     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The logs SDK did not enforce any attribute count limit, unlike spans.
SdkLoggerProvider now caps the number of attributes retained per log record
(default 128). The limit is enforced eagerly in add_attribute so a misbehaving
caller cannot grow a record's memory past the limit; rejected attributes are
counted and exposed via SdkLogRecord::dropped_attributes_count().

Configurable, in precedence order, via:
- LoggerProviderBuilder::with_max_attributes_per_log
- OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT
- OTEL_ATTRIBUTE_COUNT_LIMIT (general fallback)

Part of open-telemetry#3374
@Wassbdr Wassbdr force-pushed the feat/log-attribute-count-limit branch from 9b5265c to e4ed69c Compare July 3, 2026 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants